/*
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  Author: g0tsu
 *  Email:  g0tsu at dnmx.0rg
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

char *brightness_path;
char *max_brightness_path;

int read_sysfs_int(const char* path) {
  FILE *f = fopen(path, "r");
  if (!f) {
    return -1;
  }

  int value;

  if (fscanf(f, "%d\n", &value) != 1) {
    value = -1;
  }

  fclose(f);
  return value;
}

int write_sysfs_int(const char* path, int value) {
  FILE *f = fopen(path, "w");
  if (!f) {
    return -1;
  }

  int ret = 0;

  if(fprintf(f, "%d\n", value) < 0) {
    ret = -1;
  }

  fclose(f);
  return ret;
}

int max_brightness() {
  return read_sysfs_int(max_brightness_path);
}

int brightness() {
  return read_sysfs_int(brightness_path);
}

int set_brightness(int value) {
  int max = max_brightness();

  if (value > max)
    value = max;

  return write_sysfs_int(brightness_path, value);
}

int inc_brightness(int value) {
  int max = max_brightness();
  value = brightness() + value;

  if (value > max)
    value = max;

  return set_brightness(value);
}

int dec_brightness(int value) {
  value = brightness() - value;

  if (value < 0) {
    value = 0;
  }

  return set_brightness(value);
}

int main(int argc, char *argv[]) {
  char *path, *command;
  int value;

  if (argc < 3) {
    goto usage;
  }

  path = argv[1];
  brightness_path = malloc(BUFSIZ + 2);
  max_brightness_path = malloc(BUFSIZ + 2);

  snprintf(brightness_path, BUFSIZ, "%s/brightness", path);
  snprintf(max_brightness_path, BUFSIZ, "%s/max_brightness", path);

  command = argv[2];

  if (strcmp(command, "-get") == 0) {
    printf("%d\n", brightness());
    return 0;
  }

  if (argc < 4) {
    goto usage;
  }

  value = strtol(argv[3], NULL, 10);

  if (strcmp(command, "-set") == 0) {
    if(set_brightness(value)) {
      goto fail;
    }
    return 0;
  }

  if (strcmp(command, "-inc") == 0) {
    if(inc_brightness(value)) {
      goto fail;
    }
    return 0;
  }

  if (strcmp(command, "-dec") == 0) {
    if(dec_brightness(value)) {
      goto fail;
    }
    return 0;
  }

fail:
  perror("failed to set brightness");
  return 2;

usage:
  fprintf(stderr, "Usage: mybacklight /sys/class/leds/smc... [-get|-set|-inc|-dec] [amount]\n");
  return 1;
}
